import requests
import json
import time
import hashlib
import hmac
import base64
import uuid
from typing import Dict, Any, Optional
from datetime import datetime, timedelta
import os
from dotenv import load_dotenv
from init import db
from user.models import CmUserOrder, CmUserProduct, CmUserVip

load_dotenv()

class WeChatPayService:
    def __init__(self):
        # 微信支付配置
        self.app_id = os.getenv('WECHAT_APP_ID')
        self.mch_id = os.getenv('WECHAT_MCH_ID')
        self.mch_key = os.getenv('WECHAT_MCH_KEY')
        self.notify_url = os.getenv('WECHAT_NOTIFY_URL')
        self.api_url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi"
        
        # 验证配置
        # if not all([self.app_id, self.mch_id, self.mch_key, self.notify_url]):
        #    raise ValueError("微信支付配置不完整，请检查环境变量")
    
    def create_order(self, user_id: int, product_id: int, openid: str) -> Dict[str, Any]:
        """
        创建微信支付订单
        
        Args:
            user_id: 用户ID
            product_id: 产品ID
            openid: 用户openid
            
        Returns:
            支付订单信息
        """
        try:
            # 1. 获取产品信息
            product = db.session.query(CmUserProduct).filter(
                CmUserProduct.id == product_id,
                CmUserProduct.product_status == 1  # 假设1为启用状态
            ).first()
            
            if not product:
                return {
                    'success': False,
                    'error': '产品不存在或已下架'
                }
            
            # 2. 创建订单记录
            order = CmUserOrder(
                user_id=user_id,
                product_id=product_id,
                money=product.product_price,
                order_status=1,  # 1: 创建
                create_at=int(time.time())
            )
            
            db.session.add(order)
            db.session.commit()
            db.session.refresh(order)
            
            # 3. 生成微信支付参数
            pay_params = self._generate_pay_params(order, product, openid)
            
            return {
                'success': True,
                'data': {
                    'order_id': order.id,
                    'pay_params': pay_params
                }
            }
            
        except Exception as e:
            db.session.rollback()
            return {
                'success': False,
                'error': f'创建订单失败: {str(e)}'
            }
    
    def _generate_pay_params(self, order: CmUserOrder, product: CmUserProduct, openid: str) -> Dict[str, Any]:
        """
        生成微信支付参数
        """
        # 构建请求数据
        request_data = {
            "appid": self.app_id,
            "mchid": self.mch_id,
            "description": f"购买{product.product_name}",
            "out_trade_no": str(order.id),
            "notify_url": self.notify_url,
            "amount": {
                "total": order.money,
                "currency": "CNY"
            },
            "payer": {
                "openid": openid
            }
        }
        
        # 发送请求到微信支付API
        headers = self._get_headers(request_data)
        response = requests.post(self.api_url, json=request_data, headers=headers)
        
        if response.status_code != 200:
            raise Exception(f"微信支付API请求失败: {response.text}")
        
        result = response.json()
        
        if result.get('code'):
            raise Exception(f"微信支付API错误: {result.get('message')}")
        
        # 更新订单的第三方ID
        order.third_id = result.get('prepay_id')
        db.session.commit()
        
        # 生成小程序支付参数
        timestamp = str(int(time.time()))
        nonce_str = str(uuid.uuid4()).replace('-', '')
        
        # 构建签名字符串
        sign_str = f"{self.app_id}\n{timestamp}\n{nonce_str}\n{result.get('prepay_id')}\n"
        
        # 计算签名
        signature = self._sign_message(sign_str)
        
        return {
            "timeStamp": timestamp,
            "nonceStr": nonce_str,
            "package": f"prepay_id={result.get('prepay_id')}",
            "signType": "RSA",
            "paySign": signature
        }
    
    def _get_headers(self, data: Dict[str, Any]) -> Dict[str, str]:
        """
        生成请求头
        """
        # 这里需要根据微信支付V3的签名要求实现
        # 简化版本，实际需要实现完整的签名算法
        return {
            "Content-Type": "application/json",
            "Accept": "application/json"
        }
    
    def _sign_message(self, message: str) -> str:
        """
        签名消息
        """
        # 这里需要实现微信支付V3的签名算法
        # 简化版本，实际需要加载商户私钥进行签名
        return hashlib.sha256(message.encode()).hexdigest()
    
    def verify_payment_notify(self, notify_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        验证支付回调
        
        Args:
            notify_data: 微信支付回调数据
            
        Returns:
            验证结果
        """
        try:
            # 验证签名（需要实现完整的签名验证）
            # 这里简化处理
            
            # 解析回调数据
            resource = notify_data.get('resource', {})
            ciphertext = resource.get('ciphertext')
            nonce = resource.get('nonce')
            associated_data = resource.get('associated_data')
            
            # 解密数据（需要实现解密逻辑）
            decrypted_data = self._decrypt_data(ciphertext, nonce, associated_data)
            
            # 验证订单
            out_trade_no = decrypted_data.get('out_trade_no')
            trade_state = decrypted_data.get('trade_state')
            
            if trade_state == 'SUCCESS':
                return self._handle_success_payment(out_trade_no, decrypted_data)
            else:
                return self._handle_failed_payment(out_trade_no, decrypted_data)
                
        except Exception as e:
            return {
                'success': False,
                'error': f'验证支付回调失败: {str(e)}'
            }
    
    def _decrypt_data(self, ciphertext: str, nonce: str, associated_data: str) -> Dict[str, Any]:
        """
        解密回调数据
        """
        # 这里需要实现微信支付V3的解密逻辑
        # 简化版本，返回模拟数据
        return {
            'out_trade_no': '123456',
            'trade_state': 'SUCCESS',
            'transaction_id': 'wx_transaction_id'
        }
    
    def _handle_success_payment(self, out_trade_no: str, payment_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        处理支付成功
        """
        try:
            # 查找订单
            order = db.session.query(CmUserOrder).filter(
                CmUserOrder.id == int(out_trade_no),
                CmUserOrder.order_status == 1  # 创建状态
            ).first()
            
            if not order:
                return {
                    'success': False,
                    'error': '订单不存在或已处理'
                }
            
            # 更新订单状态
            order.order_status = 2  # 成功
            order.third_id = payment_data.get('transaction_id')
            db.session.commit()
            
            # 处理VIP升级
            self._upgrade_user_vip(order.user_id, order.product_id)
            
            return {
                'success': True,
                'message': '支付成功处理完成'
            }
            
        except Exception as e:
            db.session.rollback()
            return {
                'success': False,
                'error': f'处理支付成功失败: {str(e)}'
            }
    
    def _handle_failed_payment(self, out_trade_no: str, payment_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        处理支付失败
        """
        try:
            order = db.session.query(CmUserOrder).filter(
                CmUserOrder.id == int(out_trade_no)
            ).first()
            
            if order:
                order.order_status = 3  # 失败
                order.order_reason = payment_data.get('trade_state_desc', '支付失败')
                db.session.commit()
            
            return {
                'success': True,
                'message': '支付失败处理完成'
            }
            
        except Exception as e:
            db.session.rollback()
            return {
                'success': False,
                'error': f'处理支付失败: {str(e)}'
            }
    
    def _upgrade_user_vip(self, user_id: int, product_id: int):
        """
        升级用户VIP
        """
        # 获取产品信息
        product = db.session.query(CmUserProduct).filter(
            CmUserProduct.id == product_id
        ).first()
        
        if not product:
            return
        
        current_time = int(time.time())
        
        # 查找现有VIP记录
        vip = db.session.query(CmUserVip).filter(
            CmUserVip.user_id == user_id
        ).first()
        
        if vip:
            # 更新现有VIP
            if vip.expire_at > current_time:
                # VIP未过期，延长到期时间
                vip.expire_at += self._get_vip_duration(product.product_type)
            else:
                # VIP已过期，重新计算时间
                vip.start_at = current_time
                vip.expire_at = current_time + self._get_vip_duration(product.product_type)
        else:
            # 创建新VIP记录
            vip = CmUserVip(
                user_id=user_id,
                start_at=current_time,
                expire_at=current_time + self._get_vip_duration(product.product_type)
            )
            db.session.add(vip)
        
        db.session.commit()
    
    def _get_vip_duration(self, product_type: int) -> int:
        """
        根据产品类型获取VIP时长（秒）
        """
        duration_map = {
            1: 30 * 24 * 3600,  # 30天
            2: 90 * 24 * 3600,  # 90天
            3: 365 * 24 * 3600,  # 365天
        }
        return duration_map.get(product_type, 30 * 24 * 3600)
    
    def get_user_vip_info(self, user_id: int) -> Dict[str, Any]:
        """
        获取用户VIP信息
        """
        vip = db.session.query(CmUserVip).filter(
            CmUserVip.user_id == user_id
        ).first()
        
        if not vip:
            return {
                'success': True,
                'data': {
                    'is_vip': False,
                    'free_times': 0,
                    'expire_at': None
                }
            }
        
        current_time = int(time.time())
        is_vip = vip.expire_at > current_time
        
        return {
            'success': True,
            'data': {
                'is_vip': is_vip,
                'free_times': vip.free_times,
                'start_at': vip.start_at,
                'expire_at': vip.expire_at,
                'remaining_days': max(0, (vip.expire_at - current_time) // (24 * 3600)) if is_vip else 0
            }
        }
    
    def get_products(self, product_type: int) -> Dict[str, Any]:
        """
        获取产品列表
        """
        products = db.session.query(CmUserProduct).filter(
            CmUserProduct.product_status == 1, CmUserProduct.product_type == product_type
        ).all()
        
        product_list = []
        for product in products:
            product_list.append({
                'id': product.id,
                'name': product.product_name,
                'type': product.product_type,
                'frequency': product.product_frequency,
                'vip_level': product.product_vip_level,
                'original_price': product.product_original_price,
                'price': product.product_price,
                'description': product.product_description
            })
        
        return {
            'success': True,
            'data': {
                'products': product_list
            }
        }

# 创建全局实例
wechat_pay_service = WeChatPayService() 